package documents;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.ejml.simple.SimpleMatrix;

public class BuildMatrix {
   protected ArrayList<HashMap<Integer, Integer>> buildMatrix;
   protected ArrayList<HashMap<Integer, Integer>> buildTitleMatrix;
   protected HashMap<Integer, Integer> currentTitle;
   protected HashMap<Integer, Integer> currentWordTitle;
   protected ArrayList<String> titles;
   protected HashMap<String, Integer> words;
   protected HashMap<String, Integer> titleWords;
   protected ArrayList<String> wordList;
   protected ArrayList<String> titleWordList;
   public BuildMatrix() {
      buildMatrix = new ArrayList<HashMap<Integer, Integer>>();
      buildTitleMatrix = new ArrayList<HashMap<Integer, Integer>>();
      titles = new ArrayList<String>();
      words = new HashMap<String, Integer>();
      titleWords = new HashMap<String, Integer>();
      titleWordList = new ArrayList<String>();
      currentWordTitle = new HashMap<Integer, Integer>();
      wordList = new ArrayList<String>();
   }
   
   public void startCurrentWordTitle(){
      currentWordTitle = new HashMap<Integer, Integer>();
   }
   
   public void startTitle(final String title) {
      finishTitle();
      titles.add(title);
      currentTitle = new HashMap<Integer, Integer>();
   }
   
   public void finishTitle() {
      if (currentTitle != null) {
         if (currentTitle.size() > 0) {
            buildMatrix.add(currentTitle);
         }
         else {
            trashTitle();
         }
      }
      currentTitle = null;
   }
  
   public void finishCurrentTitle() {
      if (currentWordTitle != null) {
         if (currentWordTitle.size() > 0) {
            buildTitleMatrix.add(currentWordTitle);
         }
         else {
            titles.remove(titles.size() - 1);
         }
      }
      currentWordTitle = null;
   }   
   public void trashTitle() {
      currentTitle = null;
      titles.remove(titles.size() - 1);
   }
   
   public boolean addWord(final String word) {
      if (currentTitle == null) {
         return false;
      }
      
      Integer id = words.get(word);
      if (id == null) {
         id = words.size();
         words.put(word, id);
         wordList.add(id, word);
         currentTitle.put(id, 1);
      }
      else {
         final Integer value = currentTitle.get(id);
         if (value == null) {
            currentTitle.put(id, 1);
         }
         else {
            currentTitle.put(id, value + 1);
         }
      }
      
      return true;
   }
   
   public boolean addTitleWord(final String word) {
      if (currentWordTitle == null) {
         return false;
      }
      Integer id = titleWords.get(word);
      if (id == null) {
         id = titleWords.size();
         titleWords.put(word, id);
         titleWordList.add(id, word);
         currentWordTitle.put(id, 1);
      }
      else {
         final Integer value = currentWordTitle.get(id);
         if (value == null) {
            currentWordTitle.put(id, 1);
         }
         else {
            currentWordTitle.put(id, value + 1);
         }
      }
      
      return true;
   }
   
   public SimpleMatrix buildSimpleMatrix(boolean titleFeatureFlag) {
      finishTitle();
      final int rows = titleFeatureFlag ? titleWords.size() : words.size();
      final int columns = titles.size();
      int i, j;
      final SimpleMatrix output = new SimpleMatrix(rows, columns);
      int tmp = 0;
      
      for (i = 0; i < rows; ++i) {
         for (j = 0; j < columns; ++j) {
            final Integer val = titleFeatureFlag ? buildTitleMatrix.get(j).get(i) : buildMatrix.get(j).get(i);
            if (val != null) {
               output.set(i, j, val.doubleValue());
               tmp += val;
            }
            else {
               output.set(i, j, 0);
            }
         }
      }
      System.out.println("Total words: " + tmp);
      return output;
   }
   
   public List<String> getWordList() {
      return wordList;
   }
   
   public List<String> getTitles() {
      return titles;
   }
}
